home *** CD-ROM | disk | FTP | other *** search
- This is 3 files all glued together, mode13.h, blit13.c and pack.c
-
- mode13.h has a simple sprite def in it,
- blit13 has some simple mode13 drawing routines,
- and pack.c is a mode13 packer for faster drawing of transparent shapes.
-
- ---------------------------------------
- Transparent shapes.
-
- 1] Check EACH pixel, and only draw non-zero ones, skipping zero pixels.
- This is the easiest to program, and the slowest, as there is an extra
- cmp per pixel, and you can't use rep movs
-
- 2] Pre-pack your sprite so that it is in a form that can be quickly drawn
- transparently. The method included in this file uses a sinple
- Run Length Encoding (RLE) scheme where the the sprite is converted:
- All zero pixels are replaced with code to skip x pixels, all non-zero
- pixels are replaced with code to draw x pixels.
- Code to do this is below. For certain shapes this packing can be up
- to three times faster than method 1]
-
- ---------------------------------------
- Drawing to off-screen buffer
-
- Use the LEA (Load Effective address opp to load a far ptr)
- eg
-
- les di, dest ;load es:di with the address in the dword dest
-
- ---------------------------------------
-
- // 1st file ---------------------------------------------------------
- /*
-
- mode13.h
-
- copyright 1993, Alec Russell, ALL rights reserved
-
- 320x200, 256 color mode routines, BIOS mode 0x13
-
- */
-
- #ifndef DEF_MODE13
- #define DEF_MODE13 1
-
- #define USHORT unsigned short;
-
- // dead simple sprite struct
- typedef struct
- {
- USHORT width, height;
- BYTE far *bitmap;
- }
- shape_t;
-
- typedef unsigned char far * FARPTR;
-
- #define INPUT_STATUS_1 03dah //Input Status 1 register
- #define INPUT_STATUS_0 03dah //Input status 0 register
-
- #endif
-
- /* ----------------------- end of file ------------------------------- */
-
- // start of blit13.c---------------------------------------------------
-
- /*
- Copyright 1993, Alec Russell, ALL rights reserved
- Permission granted to use this as you wish.
-
- FILE :13blit.c
-
- mode 13 blit stuff --- MODE 13 !!! 320x200 x 256 colurs
-
-
- HISTORY:
- created : may 19, 1993
- updates :
-
- */
-
- #pragma inline
-
-
- /*
- draws to the screen directly.
-
- damn fast, bitmap drawing routine
-
- x, y, width, height all in pixels, mode 0x13 ONLY
-
- MAX width and height is 255!!!!!
-
- buffer pointer to a width by height array of bytes that are a bitmap
-
- x, y is position to display at, NO checking done for valid
- co-ords etc...
-
- WIDTH MUST BE EVEN!!!!
-
-
- */
- /* ---------------------- put_blit() --------------------- March 23,1993 */
- void put_blit(FARPTR buffer, short x, short y, short width, short height)
- {
- asm {
- push ds
- push di
-
- /* calc start address in vido mem */
- mov ax, y
- mov bx, x
- xchg ah, al
- add bx, ax
- shr ax, 1
- shr ax, 1
- add bx, ax
-
- /* set up address registers for movsw */
- mov ax, 0xa000
- mov es, ax
- mov di, bx
- lds si, buffer
-
- /* set up width and adjustment for fast blat */
- mov dx, width
- shr dx, 1
- mov bx, 320
- sub bx, width
- mov ax, height
- }
-
- /* blast each line */
- l1:
- asm {
- mov cx, dx
- rep movsw
- add di, bx
- dec ax
- jnz l1
-
- /* all done */
- pop di
- pop ds
- }
- }
-
-
-
- /*
- draws to any buffer that is 320x200 in size
-
- damn fast, bitmap drawing routine
-
- x, y, width, height all in pixels, mode 0x13 ONLY
-
- MAX width and height is 255!!!!!
-
- buffer pointer to a width by height array of bytes that are a bitmap
-
- x, y is position to display at, NO checking done for valid
- co-ords etc...
-
- WIDTH MUST BE EVEN!!!!
-
- */
- /* ---------------------- put_blit2() --------------------- March 23,1993 */
- void put_blit2(FARPTR buffer, short x, short y,
- short width, short height,
- FARPTR dest)
- {
- asm {
- push ds
- push di
-
- /* calc start address in vido mem */
- mov ax, y
- mov bx, x
- xchg ah, al
- add bx, ax
- shr ax, 1
- shr ax, 1
- add bx, ax
-
- /* set up address registers for movsw */
- les di, dest // es:di points to start dest
- add di, bx // make es:di point to x,y in dest
-
- lds si, buffer
-
- /* set up width and adjustment for fast blat */
- mov dx, width
- shr dx, 1
- mov bx, 320
- sub bx, width
- mov ax, height
- }
-
- /* blast each line */
- l1:
- asm {
- mov cx, dx
- rep movsw
- add di, bx
- dec ax
- jnz l1
-
- /* all done */
- pop di
- pop ds
- }
- }
-
-
-
- #if 0
- // C version works just fine but SLOW, kept it so you can tell
- // what the asm version does
- /* ----------------- put_blit_packed() --------------------- March 23,1993 */
- void put_blit_packed(char far *buffer, short x, short y, short width, short height)
- {
- unsigned char num;
- char far *vid;
- unsigned short i;
-
- i=y*320 + x;
- vid=MK_FP(0xa000, i);
- i=320 - width;
-
- for ( y=0; y < height; y++ )
- {
- x=0;
- while ( x < width )
- {
- if ( *buffer )
- {
- buffer++;
- num=*buffer++;
- while ( num-- )
- {
- *vid++=*buffer++;
- x++;
- }
- }
- else
- {
- buffer++;
- num=*buffer++;
- vid+=num;
- x+=num;
- }
- }
-
- vid+=i;
- }
-
-
- }
- #endif
-
- /*
-
- put a shape packed with pack shape
- run length encoded
- 0 byte next byte is number of bytes to skip
- 1 byte next byte is number of bytes to draw
-
- only useful for TRANSPARENT SHAPES
-
- MAX width and height is 255!!!!!
-
- all color zero areas will be transparent see pack.c for more
-
- */
- void put_blit_packed(FARPTR buffer, short x, short y, short width, short height)
- {
-
- asm {
- push ds
- push di
-
- /* calc start address in video mem */
- mov ax, y
- mov bx, x
- xchg ah, al
- add bx, ax
- shr ax, 1
- shr ax, 1
- add bx, ax
-
- /* set up address registers for movsw */
- mov ax, 0xa000
- mov es, ax
- mov di, bx
-
- /* to make this draw to off-screen buffer add a dest parm
- FARPTR dest, and replace the above 3 lines with
-
- les di, dest
- add, di, bx
-
- see put_blit2() for an example
-
- */
-
- lds si, buffer
-
- /* set up width and adjustment for fast blat */
- mov dx, width
- mov bx, 320
- sub bx, width
- mov ax, height
- xor ch, ch
- }
-
- /* draw/skip each line */
- l1:
- asm {
- xor dh, dh
- }
- lm0:
- asm {
- cmp byte ptr [si], 1
- je do_string
-
- /* skip black pixels */
- inc si
- mov cl, [si]
- add di, cx
- add dh, cl
- inc si
-
- /* check if done one line */
- cmp dh, dl
- jne lm0
-
- /* done one line, move to next */
- add di, bx
- dec ax
- jnz l1
-
- jmp short the_end
- }
-
- /* draw a string of pixels */
- do_string:
- asm {
- inc si
-
- mov cl, [si]
- add dh, cl
- inc si
-
- rep movsb
-
- /* check if done one line */
- cmp dh, dl
- jne lm0
-
-
- /* done one line, move to next */
- add di, bx
- dec ax
- jnz l1
- }
- the_end:
- /* all done */
- asm {
- pop di
- pop ds
- }
- }
-
-
- /*
-
- FAST and easy mode 13 clipping
-
- buffer - pointer to shape
- x, y - where to put CLIPPED section of shape
- full_width - full width of shape
- dx, dy - where in shape to start blit
- width, height - of clipped section we are drawing
-
-
- shape
-
- |<-------- full_width----->|
- ----------------------------
- | /\| |
- | dy| |
- | | | |
- |<dx->|<--width------>| |
- |------------------------ |
- | | | /\ |
- | | | | |
- | | | | |
- | | | | |
- | | this rect is | height
- | |drawn at x, y | | |
- | | on the screen | | |
- | | | | |
- | | | \/ |
- | ------------------- |
- | |
- | |
- ----------------------------
-
-
- */
- /* ---------------------- put_blit_clipped() ------------- April 24,1993 */
- void put_blit_clipped(FARPTR buffer, short x, short y, short full_width,
- short d_x, short d_y, short width, short height)
- {
- unsigned short w;
-
- asm {
- push ds
- push di
-
- /* calc w */
- mov ax, full_width
- sub ax, width
- mov w, ax
-
- /* calc start adrress in buffer */
- lds si, buffer
- mov ax, full_width
- mul word ptr d_y
- add ax, d_x
- add si, ax
-
- /* calc start address in vido mem */
- mov ax, y
- mov bx, x
- xchg ah, al
- add bx, ax
- shr ax, 1
- shr ax, 1
- add bx, ax
-
- /* set up address registers for movsb */
- mov ax, 0xa000
- mov es, ax
- mov di, bx
-
- /* set up width and adjustment for fast blat */
- mov dx, width
- mov bx, 320
- sub bx, width
- mov ax, height
- }
-
- /* blast each line */
- l1:
- asm {
- mov cx, dx
- rep movsb
- add di, bx
- add si, w
- dec ax
- jnz l1
-
- /* all done */
- pop di
- pop ds
- }
- }
-
-
- /* wait for vertical sync */
- /* ---------------------- wait_vert() -------------------- March 27,1993 */
- void wait_vert(void)
- {
- asm {
- mov dx,INPUT_STATUS_1
- }
- WaitVS:
- asm {
- in al,dx
- test al,08h
- jz WaitVS /* vertical sync is active high (1 = active) */
- }
- }
-
- /* wait for vertical sync */
- /* ---------------------- wait_vert() -------------------- March 27,1993 */
- void wait_not_vert(void)
- {
- asm {
- mov dx,INPUT_STATUS_1
- }
- WaitVS:
- asm {
- in al,dx
- test al,08h
- jnz WaitVS /* vertical sync is active high (1 = active) */
- }
- }
-
-
- /* ------------------------------ end of file ------------------------- */
-
- ; start of pack.c
-
- /*
-
- copyright 1993, Alec Russell, all rights reserved
-
- stuff to pack shapes - a utility
-
- */
-
-
-
- #include <mode13.h>
-
-
- /*
-
- pack a shape to speed up drawing TRANSPARENT shapes
-
- run length encoded
- 0 byte next byte is number of bytes to skip
- 1 byte next byte is number of bytes to draw
-
- only useful for TRANSPARENT SHAPES
-
- all color zero areas will be transparent
-
- MAX width and height is 255!!!!!
-
- packed line by line for speed
-
- this is NOT a good way to pack stuff if interested in saving space
-
- Once packed, use put_blit_packed() to draw.
- Of course you will want to pack everthing in advance.
- I usually put the function below into a stand-alone util and
- pre-pack my sprites, saving them to disk packed.
-
- */
- /* ---------------------- pack_shape() ------------------- April 15,1993 */
- void pack_shape(shape_t *shp1, shape_t *shp2)
- {
- char far *s0, far *s1, far *t;
- short num, x, y;
-
- s0=shp1->bitmap;
- s1=shp2->bitmap;
-
- for ( y=0; y < shp1->height; y++ )
- {
- x=0;
- while ( x < shp1->width )
- {
- if ( *s0 )
- {
- /* bytes isn't a zero so copy over until end of line or a zero */
- num=0;
- *s1++=1;
- t=s1; /* save where the count goes */
- s1++;
-
- /* copy and count non-zero bytes */
- while ( *s0 && x < shp1->width )
- {
- num++;
- x++;
- *s1++=*s0++;
- }
-
- /* store count */
- *t=num;
- }
- else
- {
- /* count number of zeros to skip and store count */
- num=1;
- *s1++=0;
- s0++;
- x++;
-
- while ( *s0 == 0 && x < shp1->width )
- {
- num++;
- x++;
- s0++;
- }
-
- *s1++=num;
- }
- }
- }
-
-
- }
-
- /* -------------------------- end of file -------------------------- */
-
-